package au.id.teda.broadband.usage.chart;
import android.util.Log;
import au.id.teda.broadband.usage.activity.BaseActivity;
import au.id.teda.broadband.usage.helper.AccountInfoHelper;
import au.id.teda.broadband.usage.util.DailyVolumeUsage;
import org.achartengine.ChartFactory;
import org.achartengine.model.CategorySeries;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;
import android.content.Context;
import android.graphics.Color;
import android.view.View;
import au.id.teda.broadband.usage.R;
public class StackedLineChart extends ChartBuilder {
// Debug tag pulled from main activity
//private final static String DEBUG_TAG = BaseActivity.DEBUG_TAG;
// Helper classes
private AccountInfoHelper mAccountInfo;
// Activity context to be used
private Context mContext;
private int MB = 1000000;
private double max = 0;
public StackedLineChart(Context context) {
super(context);
this.mContext = context;
mAccountInfo = new AccountInfoHelper(mContext);
}
public View getChartView(DailyVolumeUsage[] usage) {
return ChartFactory.getLineChartView(mContext,
getStackedLineChartDataSet(usage),
getStackedLineChartRenderer());
}
protected XYMultipleSeriesDataset getStackedLineChartDataSet(DailyVolumeUsage[] usage) {
if(mAccountInfo.isAccountAnyTime()){
return getAnytimeSeriesDataset(usage);
} else {
return getPeakOffpeakSeriesDataset(usage);
}
}
private XYMultipleSeriesRenderer getStackedLineChartRenderer() {
if(mAccountInfo.isAccountAnyTime()){
return getAnytimeSeriesRenderer();
} else {
return getPeakOffpeakSeriesRenderer();
}
}
private XYMultipleSeriesDataset getAnytimeSeriesDataset(DailyVolumeUsage[] usage) {
// Set daily accum objects and initialise
long anytimeDailyAccum = 0;
long uploadDailyAccum = 0;
long quotaDailyAccum = 0;
// Set String value categories for graph
CategorySeries anytimeSeries = new CategorySeries(mContext.getString(R.string.chart_data_series_anytime));
CategorySeries uploadSeries = new CategorySeries(mContext.getString(R.string.chart_data_series_upload));
CategorySeries anytimeQuotaSeries = new CategorySeries(mContext.getString(R.string.chart_data_series_anytime_quota));
// Get average daily useage
long quotaDaily = mAccountInfo.getAnyTimeQuotaDailyMb();
for (DailyVolumeUsage volumeUsage : usage) {
// Get values from array
Long anytime = (volumeUsage.anytime / MB);
Long upload = (volumeUsage.uploads / MB);
// Take off upload usage
Long anytimeUsage = anytime - upload;
Long uploadUsage = upload;
// Calculate accumalitive values
anytimeDailyAccum = anytimeDailyAccum + anytimeUsage;
uploadDailyAccum = uploadDailyAccum + uploadUsage;
quotaDailyAccum = quotaDailyAccum + quotaDaily;
// Calculate stacked values
long anytimeStacked = anytimeDailyAccum;
long uploadStacked = anytimeDailyAccum + uploadDailyAccum;
// Add current cursor values to data series
anytimeSeries.add(anytimeStacked);
uploadSeries.add(uploadStacked);
anytimeQuotaSeries.add(quotaDailyAccum);
//Log.d(DEBUG_TAG, "anytimeUsage:" + anytimeUsage + " uploadUsage:" + uploadUsage + " quotaDaily:" + quotaDaily);
//Log.d(DEBUG_TAG, "anytimeDailyAccum:" + anytimeDailyAccum + " uploadDailyAccum:" + uploadDailyAccum + " quotaDailyAccum:" + quotaDailyAccum);
// Set max data usage for rendering graph
if (max <= uploadDailyAccum) {
max = uploadDailyAccum * 1.05;
}
if (max <= quotaDailyAccum ){
max = quotaDailyAccum * 1.05;
}
}
XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
dataset.addSeries(uploadSeries.toXYSeries());
dataset.addSeries(anytimeSeries.toXYSeries());
dataset.addSeries(anytimeQuotaSeries.toXYSeries());
return dataset;
}
private XYMultipleSeriesDataset getPeakOffpeakSeriesDataset(DailyVolumeUsage[] usage) {
// Set daily accum objects and initialise
long peakDailyAccum = 0;
long offpeakDailyAccum = 0;
long uploadDailyAccum = 0;
long quotaDailyAccum = 0;
// Set String value categories for graph
CategorySeries peakSeries = new CategorySeries(mContext.getString(R.string.chart_data_series_peak));
CategorySeries offpeakSeries = new CategorySeries(mContext.getString(R.string.chart_data_series_offpeak));
CategorySeries uploadSeries = new CategorySeries(mContext.getString(R.string.chart_data_series_upload));
CategorySeries quotaSeries = new CategorySeries(mContext.getString(R.string.chart_data_series_quota));
// Get average daily usage
long dailyQuota = mAccountInfo.getPeakQuotaDailyMb() + mAccountInfo.getOffpeakQuotaDailyMb();
for (DailyVolumeUsage volumeUsage : usage) {
// Get values from array & take off upload guess
Long peak = (volumeUsage.peak / MB);
Long offpeak = (volumeUsage.offpeak / MB);
Long upload = (volumeUsage.uploads / MB);
Long quota = dailyQuota;
// Calculate usage values
Long peakUsage = peak - peakUploadGuess(peak, offpeak, upload);
Long offpeakUsage = offpeak - offpeakUploadGuess(peak, offpeak, upload);
Long uploadUsage = upload;
// Set daily accumulated usage for stacking chart
peakDailyAccum = peakDailyAccum + peakUsage;
offpeakDailyAccum = offpeakDailyAccum + offpeakUsage;
uploadDailyAccum = uploadDailyAccum + uploadUsage;
quotaDailyAccum = quotaDailyAccum + quota;
// Make data stacked for chart.
long peakStacked = peakDailyAccum;
long offpeakStacked = peakStacked + offpeakDailyAccum;
long uploadStacked = offpeakStacked + uploadDailyAccum;
// Add current cursor values to data series
peakSeries.add(peakStacked);
offpeakSeries.add(offpeakStacked);
uploadSeries.add(uploadStacked);
quotaSeries.add(quotaDailyAccum);
// Set max data usage for rendering graph
if (max < uploadStacked) {
max = uploadStacked * 1.05;
}
if (max < quotaDailyAccum) {
max = quotaDailyAccum * 1.05;
}
//Log.d(DEBUG_TAG, "dailyQuota:" + dailyQuota + " | quotaDailyAccum:" + quotaDailyAccum);
//Log.d(DEBUG_TAG, "peakStacked:" + peakStacked + " offpeakStacked:" + offpeakStacked + " uploadStacked:" + uploadStacked + " max:" + max);
//Log.d(DEBUG_TAG, "peakUsage:" + peakUsage + " offpeakUsage:" + offpeakUsage + " uploadUsage:" + uploadUsage);
}
XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
dataset.addSeries(uploadSeries.toXYSeries());
dataset.addSeries(offpeakSeries.toXYSeries());
dataset.addSeries(peakSeries.toXYSeries());
dataset.addSeries(quotaSeries.toXYSeries());
return dataset;
}
private XYMultipleSeriesRenderer getPeakOffpeakSeriesRenderer() {
// Set render object and initialise
XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
// Set series render object
XYSeriesRenderer r = new XYSeriesRenderer();
/** Cannot get this one to work for depreciated call below
* FillOutsideLine fill = FillOutsideLine.BOUNDS_BELOW;
* fill.setColor(Color.MAGENTA);
* xyRenderer.addFillOutsideLine(fill);
*/
// Upload series render settings
r.setColor(getUploadColor());
r.setFillBelowLine(true);
r.setFillBelowLineColor(getUploadColor());
r.setFillPoints(false);
r.setLineWidth(0);
renderer.addSeriesRenderer(r);
// Offpeak series render settings
r = new XYSeriesRenderer();
r.setColor(getOffpeakColor());
r.setFillBelowLine(true);
r.setFillBelowLineColor(getOffpeakColor());
r.setFillPoints(false);
r.setLineWidth(1);
renderer.addSeriesRenderer(r);
// peak series render settings
r = new XYSeriesRenderer();
r.setColor(getPeakColor());
r.setFillBelowLine(true);
r.setFillBelowLineColor(getPeakColor());
r.setFillPoints(false);
r.setLineWidth(1);
renderer.addSeriesRenderer(r);
// Quota daily series render settings
r = new XYSeriesRenderer();
r.setColor(getOffpeakTrendColor());
r.setFillBelowLine(false);
r.setFillPoints(false);
r.setLineWidth(2);
renderer.addSeriesRenderer(r);
// Graph render settings
renderer.setApplyBackgroundColor(true);
renderer.setBackgroundColor(Color.TRANSPARENT);
renderer.setMarginsColor(getBackgroundColor());
renderer.setPanEnabled(false, false);
renderer.setShowLegend(true);
renderer.setFitLegend(true);
renderer.setLabelsTextSize(getLabelsTextSize(12));
renderer.setLegendTextSize(getLabelsTextSize(12));
renderer.setAxesColor(getLabelColor());
renderer.setAntialiasing(true);
renderer.setXAxisMin(0);
renderer.setXAxisMax(getChartDays());
renderer.setYAxisMin(0);
renderer.setYAxisMax(getMaxDataUsage());
renderer.setAxesColor(getLabelColor());
renderer.setLabelsColor(getLabelColor());
renderer.setXLabelsColor(getLabelColor());
// Set point size to 0 to hide
renderer.setPointSize(0f);
return renderer;
}
private XYMultipleSeriesRenderer getAnytimeSeriesRenderer() {
// Set render object and initialise
XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
// Set series render object
XYSeriesRenderer r;
// Anytime line chart
r = new XYSeriesRenderer();
r.setColor(getPeakColor());
r.setFillBelowLine(true);
r.setFillBelowLineColor(getUploadColor());
r.setFillPoints(false);
r.setLineWidth(0);
renderer.addSeriesRenderer(r);
// Upload line chart
r = new XYSeriesRenderer();
r.setColor(getPeakColor());
r.setFillBelowLine(true);
r.setFillBelowLineColor(getPeakColor());
r.setFillPoints(false);
r.setLineWidth(0);
renderer.addSeriesRenderer(r);
// Quota line
r = new XYSeriesRenderer();
r.setColor(getPeakTrendColor());
r.setFillBelowLine(false);
r.setFillPoints(false);
r.setLineWidth(2);
renderer.addSeriesRenderer(r);
// Graph render settings
renderer.setApplyBackgroundColor(true);
renderer.setBackgroundColor(Color.TRANSPARENT);
renderer.setMarginsColor(getBackgroundColor());
renderer.setPanEnabled(false, false);
renderer.setShowLegend(true);
renderer.setFitLegend(true);
renderer.setLabelsTextSize(getLabelsTextSize(12));
renderer.setLegendTextSize(getLabelsTextSize(12));
renderer.setAxesColor(getLabelColor());
renderer.setAntialiasing(true);
renderer.setXAxisMin(0);
renderer.setXAxisMax(getChartDays());
renderer.setYAxisMin(0);
renderer.setYAxisMax(getMaxDataUsage());
renderer.setAxesColor(getLabelColor());
renderer.setLabelsColor(getLabelColor());
renderer.setXLabelsColor(getLabelColor());
// Set point size to 0 to hide
renderer.setPointSize(0f);
return renderer;
}
public double getMaxDataUsage() {
return max;
}
}